package utils_jwt

import (
	"fmt"
	"github.com/golang-jwt/jwt"
	"go.uber.org/zap"
	"mall-portalv2/global"
	"net/http"
	"strings"
	"time"
)

/**
* Author: joker
* TODO: test
* Date: 2022/8/22
* Time: 下午5:37
**/

type JwtConf struct {
	AgentUserIdHeader string
	JwtSecret         []byte
	Issuer            string
}

type Claims struct {
	Uid  int64
	Zone string
	jwt.StandardClaims
}

func (this *JwtConf) GetAgentUserIdFromHeader(c *http.Request) string {
	return c.Header.Get(this.AgentUserIdHeader)
}

func (this *JwtConf) GetAccessToken(headAuthorization string) string {
	return strings.TrimPrefix(headAuthorization, "Bearer ")
}

func (this *JwtConf) SetAgentUserIdHeader(r *http.Request, agentUserId string) {
	r.Header.Set(this.AgentUserIdHeader, agentUserId)
}

func (this *JwtConf) GenerateToken(userId int64) (string, time.Time, error) {
	nowTime := time.Now()
	expireTime := nowTime.Add(24 * time.Hour)
	claims := Claims{
		userId,
		"TS",
		jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(),
			Issuer:    this.Issuer,
			Audience:  fmt.Sprintf("%d", userId),
		},
	}
	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
	token, err := tokenClaims.SignedString([]byte(this.JwtSecret))

	return fmt.Sprintf("%s", token), expireTime, err
}

func (this *JwtConf) ParseToken(token string) (*Claims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		if keyId, ok := token.Header["kid"].(string); ok {
			global.Log.Info("测试", zap.Any("keyid", keyId))
		}
		return this.JwtSecret, nil
	})
	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}

	return nil, err
}

func (this *JwtConf) ParseToken2(token string) (*Claims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		if keyId, ok := token.Header["kid"].(string); ok {
			//todo：可能是测试
			if keyId == "signkeyid1" {
				return []byte("signkeystr1"), nil
			}
			if keyId == "signkeyid2" {
				return []byte("signkey53b66623fa06538c3cbba3b7d5c64eec2ef22d956bae78c724a7283168c58c55"), nil
			}
			// 兼容旧版本
			if keyId == "ggassist_dc_723e_0cd3" {
				return []byte("Jfc4Z4Ur15JwUBuvUQD5wg7Nu8+l+HscqYlfofbyJdZeHlCiiWYAjjrf8Q8rN3ah"), nil
			}
			// 兼容旧版本
			if keyId == "dc_smartlife_5270" {
				return []byte("Jfc4Z4Ur15JwUBuvUQD5wg7Nu8+l+HscqYlfofbyJdZeHlCiiWYAjjrf8Q8rN3ah"), nil
			}
		}
		return []byte("signkeySync3498cda4d421b6345a571fe34aaad286a610912100a0bbb7c0cff66ea4098102"), nil
	})
	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}

	return nil, err
}
